package com.yic.module.mes.service.report;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.yic.framework.common.util.collection.CollectionUtils;
import com.yic.module.mes.dal.dataobject.mo.MoDO;
import com.yic.module.mes.dal.dataobject.moroute.MoRouteDO;
import com.yic.module.mes.dal.dataobject.report.ReportDO;
import com.yic.module.mes.service.moroute.MoRouteService;
import com.yic.module.system.enums.dict.MesProcessLinkEnum;
import com.yic.module.system.enums.dict.MesSerialTypeEnum;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;

import static com.yic.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.yic.module.mes.enums.ErrorCodeConstants.*;

/**
 * @Author: Ljx
 * @createTime: 2023年11月27日 16:25:18
 * @version: v1.0.0
 * @Description: 批量报工实现类
 */
@Service("batch")
public class BatchReportTempleteImpl extends ReportTemplete {

    @Resource
    private ReportService reportService;
    @Resource
    private MoRouteService moRouteService;

    @Override
    protected void checkReportType(MoDO moDO) {
        if (!moDO.getSnType().equals(MesSerialTypeEnum.NO.getMesSerialType())) {
            throw exception(REPORT_TYPE_NOT_MATE);
        }
    }

    @Override
    protected void checkSerialNo(Long moId, Long moRouteId, String serialNo) {
        //无需做流水号校验
    }

    @Override
    protected void checkProcess(Long moId, Long moRouteId, BigDecimal reportAmount, BigDecimal produceAmount, String serialNo) {
        // 获取工单工艺路线
        List<MoRouteDO> moRoutes = moRouteService.getMoRouteByMoId(moId);
        if (CollectionUtil.isEmpty(moRoutes)) {
            throw exception(MO_ROUTE_NOT_EXISTS);
        }
        MoRouteDO curRoute = null;
        MoRouteDO upRoute = null;
        for (int i = 0; i < moRoutes.size(); i++) {
            MoRouteDO moRoute = moRoutes.get(i);
            // 获取当前工序
            if (moRoute.getId().equals(moRouteId)) {
                curRoute = moRoute;
                if (moRoute.getSubsequence() > 1) { // 获取上一道工序
                    List<MoRouteDO> moRouteDOS = moRoutes.stream().filter(moRouteDO -> moRouteDO.getSubsequence().equals(moRoute.getSubsequence() - 1)).collect(Collectors.toList());
                    if (CollectionUtil.isEmpty(moRouteDOS)) {
                        throw exception(MO_ROUTE_ERROR);
                    }
                    upRoute = CollectionUtils.getFirst(moRouteDOS);
                }
                break;
            }
        }
        //校验当前工序报工数量不允许超过排产数量
        List<ReportDO> list = reportService.getReportByMoRouteId(moRouteId);
        if (CollectionUtil.isNotEmpty(list)) {
            BigDecimal amount = list.stream().map(ReportDO::getReportAmount).reduce(BigDecimal.ZERO, BigDecimal::add); //已报功数量
            if (produceAmount.subtract(amount).compareTo(reportAmount) < 0) {
                throw exception(REPORT_AMOUNT_EXCEED);
            }
        }
        //校验上道工序
        if (ObjectUtil.isNotEmpty(upRoute) && upRoute.getLink().equals(MesProcessLinkEnum.ES.getMesProcessLink())) {
            // 查询上道工序已报工数量
            BigDecimal upAmount = reportService.getReportAmountByMoRouteId(upRoute.getId());
            if (upAmount.compareTo(BigDecimal.ZERO) <= 0) {
                throw exception(REPORT_NOT_UP_PROCESS);
            }
            // 查询当前工序已报工数量
            BigDecimal curAmount = reportService.getReportAmountByMoRouteId(curRoute.getId());
            // 计算允许报工数量
            BigDecimal tem = upAmount.subtract(curAmount);
            if (reportAmount.compareTo(tem) > 0) {
                throw exception(REPORT_AMOUNT_EXCEED_UP_PROCESS, tem);
            }
        }
    }

    @Override
    protected void reduceInventory() {
        //TODO 出库
    }

    @Override
    protected void increaseInventory() {
        //TODO 入库
    }

    @Override
    protected void saveProduce() {
        //TODO 生成生产信息
    }
}
